home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / actionrp / lrogue0.1 / lrogue0 / rogue / move.c < prev    next >
C/C++ Source or Header  |  1992-09-26  |  10KB  |  541 lines

  1. /*
  2.  * move.c
  3.  *
  4.  * This source herein may be modified and/or distributed by anybody who
  5.  * so desires, with the following restrictions:
  6.  *    1.)  No portion of this notice shall be removed.
  7.  *    2.)  Credit shall not be taken for the creation of this source.
  8.  *    3.)  This code is not to be traded, sold, or used for personal
  9.  *         gain or profit.
  10.  *
  11.  */
  12.  
  13. #ifndef CURSES
  14. #include <curses.h>
  15. #endif CURSES
  16. #include "rogue.h"
  17.  
  18. short m_moves = 0;
  19. boolean jump = 1;
  20. char *you_can_move_again = "you can move again";
  21.  
  22. extern short cur_room, halluc, blind, levitate;
  23. extern short cur_level, max_level;
  24. extern short bear_trap, haste_self, confused;
  25. extern short e_rings, regeneration, auto_search;
  26. extern char hunger_str[];
  27. extern boolean being_held, interrupted, r_teleport;
  28.  
  29. one_move_rogue(dirch, pickup)
  30. short dirch, pickup;
  31. {
  32.     short row, col;
  33.     object *obj;
  34.     char desc[DCOLS];
  35.     short n, status;
  36.  
  37.     row = rogue.row;
  38.     col = rogue.col;
  39.  
  40.     if (confused) {
  41.         dirch = gr_dir();
  42.     }
  43.     get_dir_rc(dirch, &row, &col, 1);
  44.  
  45.     if (!can_move(rogue.row, rogue.col, row, col)) {
  46.         return(MOVE_FAILED);
  47.     }
  48.     if (being_held || bear_trap) {
  49.         if (!(dungeon[row][col] & MONSTER)) {
  50.             if (being_held) {
  51.                 message("you are being held", 1);
  52.             } else {
  53.                 message("you are still stuck in the bear trap", 0);
  54.                 (void) reg_move();
  55.             }
  56.             return(MOVE_FAILED);
  57.         }
  58.     }
  59.     if (r_teleport) {
  60.         if (rand_percent(R_TELE_PERCENT)) {
  61.             tele();
  62.             return(STOPPED_ON_SOMETHING);
  63.         }
  64.     }
  65.     if (dungeon[row][col] & MONSTER) {
  66.         rogue_hit(object_at(&level_monsters, row, col), 0);
  67.         (void) reg_move();
  68.         return(MOVE_FAILED);
  69.     }
  70.     if (dungeon[row][col] & DOOR) {
  71.         if (cur_room == PASSAGE) {
  72.             cur_room = get_room_number(row, col);
  73.             light_up_room(cur_room);
  74.             wake_room(cur_room, 1, row, col);
  75.         } else {
  76.             light_passage(row, col);
  77.         }
  78.     } else if ((dungeon[rogue.row][rogue.col] & DOOR) &&
  79.            (dungeon[row][col] & TUNNEL)) {
  80.         light_passage(row, col);
  81.         wake_room(cur_room, 0, rogue.row, rogue.col);
  82.         darken_room(cur_room);
  83.         cur_room = PASSAGE;
  84.     } else if (dungeon[row][col] & TUNNEL) {
  85.             light_passage(row, col);
  86.     }
  87.     mvaddch(rogue.row, rogue.col, get_dungeon_char(rogue.row, rogue.col));
  88.     mvaddch(row, col, rogue.fchar);
  89.  
  90.     if (!jump) {
  91.         refresh();
  92.     }
  93.     rogue.row = row;
  94.     rogue.col = col;
  95.     if (dungeon[row][col] & OBJECT) {
  96.         if (levitate && pickup) {
  97.             return(STOPPED_ON_SOMETHING);
  98.         }
  99.         if (pickup && !levitate) {
  100.             if (obj = pick_up(row, col, &status)) {
  101.                 get_desc(obj, desc);
  102.                 if (obj->what_is == GOLD) {
  103.                     free_object(obj);
  104.                     goto NOT_IN_PACK;
  105.                 }
  106.             } else if (!status) {
  107.                 goto MVED;
  108.             } else {
  109.                 goto MOVE_ON;
  110.             }
  111.         } else {
  112. MOVE_ON:
  113.             obj = object_at(&level_objects, row, col);
  114.             (void) strcpy(desc, "moved onto ");
  115.             get_desc(obj, desc+11);
  116.             goto NOT_IN_PACK;
  117.         }
  118.         n = strlen(desc);
  119.         desc[n] = '(';
  120.         desc[n+1] = obj->ichar;
  121.         desc[n+2] = ')';
  122.         desc[n+3] = 0;
  123. NOT_IN_PACK:
  124.         message(desc, 1);
  125.         (void) reg_move();
  126.         return(STOPPED_ON_SOMETHING);
  127.     }
  128.     if (dungeon[row][col] & (DOOR | STAIRS | TRAP)) {
  129.         if ((!levitate) && (dungeon[row][col] & TRAP)) {
  130.             trap_player(row, col);
  131.         }
  132.         (void) reg_move();
  133.         return(STOPPED_ON_SOMETHING);
  134.     }
  135. MVED:    if (reg_move()) {            /* fainted from hunger */
  136.             return(STOPPED_ON_SOMETHING);
  137.     }
  138.     return((confused ? STOPPED_ON_SOMETHING : MOVED));
  139. }
  140.  
  141. multiple_move_rogue(dirch)
  142. {
  143.     short row, col;
  144.     short m;
  145.  
  146.     switch(dirch) {
  147.     case '\010':
  148.     case '\012':
  149.     case '\013':
  150.     case '\014':
  151.     case '\031':
  152.     case '\025':
  153.     case '\016':
  154.     case '\002':
  155.         do {
  156.             row = rogue.row;
  157.             col = rogue.col;
  158.             if (((m = one_move_rogue((dirch + 96), 1)) == MOVE_FAILED) ||
  159.                 (m == STOPPED_ON_SOMETHING) ||
  160.                 interrupted) {
  161.                 break;
  162.             }
  163.         } while (!next_to_something(row, col));
  164.         break;
  165.     case 'H':
  166.     case 'J':
  167.     case 'K':
  168.     case 'L':
  169.     case 'B':
  170.     case 'Y':
  171.     case 'U':
  172.     case 'N':
  173.         while (    (!interrupted) &&
  174.                 (one_move_rogue((dirch + 32), 1) == MOVED)) ;
  175.         break;
  176.     }
  177. }
  178.  
  179. is_passable(row, col)
  180. register row, col;
  181. {
  182.     if ((row < MIN_ROW) || (row > (DROWS - 2)) || (col < 0) ||
  183.         (col > (DCOLS-1))) {
  184.         return(0);
  185.     }
  186.     if (dungeon[row][col] & HIDDEN) {
  187.         return((dungeon[row][col] & TRAP) ? 1 : 0);
  188.     }
  189.     return(dungeon[row][col] & (FLOOR | TUNNEL | DOOR | STAIRS | TRAP));
  190. }
  191.  
  192. next_to_something(drow, dcol)
  193. register drow, dcol;
  194. {
  195.     short i, j, i_end, j_end, row, col;
  196.     short pass_count = 0;
  197.     unsigned short s;
  198.  
  199.     if (confused) {
  200.         return(1);
  201.     }
  202.     if (blind) {
  203.         return(0);
  204.     }
  205.     i_end = (rogue.row < (DROWS-2)) ? 1 : 0;
  206.     j_end = (rogue.col < (DCOLS-1)) ? 1 : 0;
  207.  
  208.     for (i = ((rogue.row > MIN_ROW) ? -1 : 0); i <= i_end; i++) {
  209.         for (j = ((rogue.col > 0) ? -1 : 0); j <= j_end; j++) {
  210.             if ((i == 0) && (j == 0)) {
  211.                 continue;
  212.             }
  213.             if (((rogue.row+i) == drow) && ((rogue.col+j) == dcol)) {
  214.                 continue;
  215.             }
  216.             row = rogue.row + i;
  217.             col = rogue.col + j;
  218.             s = dungeon[row][col];
  219.             if (s & HIDDEN) {
  220.                 continue;
  221.             }
  222.             /* If the rogue used to be right, up, left, down, or right of
  223.              * row,col, and now isn't, then don't stop */
  224.             if (s & (MONSTER | OBJECT | STAIRS)) {
  225.                 if (((row == drow) || (col == dcol)) &&
  226.                     (!((row == rogue.row) || (col == rogue.col)))) {
  227.                     continue;
  228.                 }
  229.                 return(1);
  230.             }
  231.             if (s & TRAP) {
  232.                 if (!(s & HIDDEN)) {
  233.                     if (((row == drow) || (col == dcol)) &&
  234.                         (!((row == rogue.row) || (col == rogue.col)))) {
  235.                         continue;
  236.                     }
  237.                     return(1);
  238.                 }
  239.             }
  240.             if ((((i - j) == 1) || ((i - j) == -1)) && (s & TUNNEL)) {
  241.                 if (++pass_count > 1) {
  242.                     return(1);
  243.                 }
  244.             }
  245.             if ((s & DOOR) && ((i == 0) || (j == 0))) {
  246.                     return(1);
  247.             }
  248.         }
  249.     }
  250.     return(0);
  251. }
  252.  
  253. can_move(row1, col1, row2, col2) 
  254. {
  255.     if (!is_passable(row2, col2)) {
  256.         return(0);
  257.     }
  258.     if ((row1 != row2) && (col1 != col2)) {
  259.         if ((dungeon[row1][col1]&DOOR)||(dungeon[row2][col2]&DOOR)) {
  260.             return(0);
  261.         }
  262.         if ((!dungeon[row1][col2]) || (!dungeon[row2][col1])) {
  263.             return(0);
  264.         }
  265.     }
  266.     return(1);
  267. }
  268.  
  269. move_onto()
  270. {
  271.     short ch;
  272.     boolean first_miss = 1;
  273.  
  274.     while (!is_direction(ch = rgetchar())) {
  275.         sound_bell();
  276.         if (first_miss) {
  277.             message("direction? ", 0);
  278.             first_miss = 0;
  279.         }
  280.     }
  281.     check_message();
  282.     if (ch != CANCEL) {
  283.         (void) one_move_rogue(ch, 0);
  284.     }
  285. }
  286.  
  287. boolean
  288. is_direction(c)
  289. {
  290.     return(
  291.         (c == 'h') ||
  292.         (c == 'j') ||
  293.         (c == 'k') ||
  294.         (c == 'l') ||
  295.         (c == 'b') ||
  296.         (c == 'y') ||
  297.         (c == 'u') ||
  298.         (c == 'n') ||
  299.         (c == CANCEL)
  300.         );
  301. }
  302.  
  303. boolean
  304. check_hunger(messages_only)
  305. boolean messages_only;
  306. {
  307.     register short i, n;
  308.     boolean fainted = 0;
  309.  
  310.     if (rogue.moves_left == HUNGRY) {
  311.         (void) strcpy(hunger_str, "hungry");
  312.         message(hunger_str, 0);
  313.         print_stats(STAT_HUNGER);
  314.     }
  315.     if (rogue.moves_left == WEAK) {
  316.         (void) strcpy(hunger_str, "weak");
  317.         message(hunger_str, 1);
  318.         print_stats(STAT_HUNGER);
  319.     }
  320.     if (rogue.moves_left <= FAINT) {
  321.         if (rogue.moves_left == FAINT) {
  322.             (void) strcpy(hunger_str, "faint");
  323.             message(hunger_str, 1);
  324.             print_stats(STAT_HUNGER);
  325.         }
  326.         n = get_rand(0, (FAINT - rogue.moves_left));
  327.         if (n > 0) {
  328.             fainted = 1;
  329.             if (rand_percent(40)) {
  330.                 rogue.moves_left++;
  331.             }
  332.             message("you faint", 1);
  333.             for (i = 0; i < n; i++) {
  334.                 if (coin_toss()) {
  335.                     mv_mons();
  336.                 }
  337.             }
  338.             message(you_can_move_again, 1);
  339.         }
  340.     }
  341.     if (messages_only) {
  342.         return(fainted);
  343.     }
  344.     if (rogue.moves_left <= STARVE) {
  345.         killed_by((object *) 0, STARVATION);
  346.     }
  347.  
  348.     switch(e_rings) {
  349.     /*case -2:
  350.         Subtract 0, i.e. do nothing.
  351.         break;*/
  352.     case -1:
  353.         rogue.moves_left -= (rogue.moves_left % 2);
  354.         break;
  355.     case 0:
  356.         rogue.moves_left--;
  357.         break;
  358.     case 1:
  359.         rogue.moves_left--;
  360.         (void) check_hunger(1);
  361.         rogue.moves_left -= (rogue.moves_left % 2);
  362.         break;
  363.     case 2:
  364.         rogue.moves_left--;
  365.         (void) check_hunger(1);
  366.         rogue.moves_left--;
  367.         break;
  368.     }
  369.     return(fainted);
  370. }
  371.  
  372. boolean
  373. reg_move()
  374. {
  375.     boolean fainted;
  376.  
  377.     if ((rogue.moves_left <= HUNGRY) || (cur_level >= max_level)) {
  378.         fainted = check_hunger(0);
  379.     } else {
  380.         fainted = 0;
  381.     }
  382.  
  383.     mv_mons();
  384.  
  385.     if (++m_moves >= 120) {
  386.         m_moves = 0;
  387.         wanderer();
  388.     }
  389.     if (halluc) {
  390.         if (!(--halluc)) {
  391.             unhallucinate();
  392.         } else {
  393.             hallucinate();
  394.         }
  395.     }
  396.     if (blind) {
  397.         if (!(--blind)) {
  398.             unblind();
  399.         }
  400.     }
  401.     if (confused) {
  402.         if (!(--confused)) {
  403.             unconfuse();
  404.         }
  405.     }
  406.     if (bear_trap) {
  407.         bear_trap--;
  408.     }
  409.     if (levitate) {
  410.         if (!(--levitate)) {
  411.             message("you float gently to the ground", 1);
  412.             if (dungeon[rogue.row][rogue.col] & TRAP) {
  413.                 trap_player(rogue.row, rogue.col);
  414.             }
  415.         }
  416.     }
  417.     if (haste_self) {
  418.         if (!(--haste_self)) {
  419.             message("you feel yourself slowing down", 0);
  420.         }
  421.     }
  422.     heal();
  423.     if (auto_search > 0) {
  424.         search(auto_search, auto_search);
  425.     }
  426.     return(fainted);
  427. }
  428.  
  429. rest(count)
  430. {
  431.     int i;
  432.  
  433.     interrupted = 0;
  434.  
  435.     for (i = 0; i < count; i++) {
  436.         if (interrupted) {
  437.             break;
  438.         }
  439.         (void) reg_move();
  440.     }
  441. }
  442.  
  443. gr_dir()
  444. {
  445.     short d;
  446.  
  447.     d = get_rand(1, 8);
  448.  
  449.     switch(d) {
  450.         case 1:
  451.             d = 'j';
  452.             break;
  453.         case 2:
  454.             d = 'k';
  455.             break;
  456.         case 3:
  457.             d = 'l';
  458.             break;
  459.         case 4:
  460.             d = 'h';
  461.             break;
  462.         case 5:
  463.             d = 'y';
  464.             break;
  465.         case 6:
  466.             d = 'u';
  467.             break;
  468.         case 7:
  469.             d = 'b';
  470.             break;
  471.         case 8:
  472.             d = 'n';
  473.             break;
  474.     }
  475.     return(d);
  476. }
  477.  
  478. heal()
  479. {
  480.     static short heal_exp = -1, n, c = 0;
  481.     static boolean alt;
  482.  
  483.     if (rogue.hp_current == rogue.hp_max) {
  484.         c = 0;
  485.         return;
  486.     }
  487.     if (rogue.exp != heal_exp) {
  488.         heal_exp = rogue.exp;
  489.  
  490.         switch(heal_exp) {
  491.         case 1:
  492.             n = 20;
  493.             break;
  494.         case 2:
  495.             n = 18;
  496.             break;
  497.         case 3:
  498.             n = 17;
  499.             break;
  500.         case 4:
  501.             n = 14;
  502.             break;
  503.         case 5:
  504.             n = 13;
  505.             break;
  506.         case 6:
  507.             n = 10;
  508.             break;
  509.         case 7:
  510.             n = 9;
  511.             break;
  512.         case 8:
  513.             n = 8;
  514.             break;
  515.         case 9:
  516.             n = 7;
  517.             break;
  518.         case 10:
  519.             n = 4;
  520.             break;
  521.         case 11:
  522.             n = 3;
  523.             break;
  524.         case 12:
  525.         default:
  526.             n = 2;
  527.         }
  528.     }
  529.     if (++c >= n) {
  530.         c = 0;
  531.         rogue.hp_current++;
  532.         if (alt = !alt) {
  533.             rogue.hp_current++;
  534.         }
  535.         if ((rogue.hp_current += regeneration) > rogue.hp_max) {
  536.             rogue.hp_current = rogue.hp_max;
  537.         }
  538.         print_stats(STAT_HP);
  539.     }
  540. }
  541.